var _super = null; //require("SomeSuperClass");//继承的写法
var _tables = {};
var ConfTable = {
  _setProp: _setProp,
  _setFunction: _setFunction,
  createWithSource: function (name, source) {
    var n = {};
    if (_super !== null) {
      _super._setProp(n);
      _super._setFunction(n);
    }
    _setProp(n);
    _setFunction(n);
    n.init(source);
    _tables[name] = n;
    n.name = name;
    return n;
  },
  getConfTable: function (name) {
    return _tables[name];
  },
  convert: function (cls, value) {
    //cc.log("类型转换"+key+value);
    var i;
    var tmps, rs;
    if (cls == 'bool') {
      return parseInt(value) != 0;
    }
    if (cls == 'string') {
      return value;
    }
    if (cls == 'float') {
      return parseFloat(value);
    }
    if (cls == 'int') {
      return parseInt(value);
    }
    if (cls == 'int[]') {
      if (value == '') {
        return [];
      } else {
        tmps = value.split(',');
        rs = [];
        for (i = 0; i < tmps.length; i++) {
          let n = tmps[i];
          rs[i] = parseInt(n);
        }
        return rs;
      }
    }
    if (cls == 'int[][]') {
      if (value == '') {
        return [];
      } else {
        tmps = value.split('|');
        rs = [];
        for (i = 0; i < tmps.length; i++) {
          let n = tmps[i];
          let sub_temps = n.split(',');
          let sub_rs = [];
          for (let j = 0; j < sub_temps.length; j++) {
            sub_rs[j] = parseInt(sub_temps[j]);
          }
          rs[i] = sub_rs;
        }
        return rs;
      }
    }
    if (cls == 'float[]') {
      if (value == '') {
        return [];
      } else {
        tmps = value.split(',');
        rs = [];
        for (i = 0; i < tmps.length; i++) {
          rs[i] = parseFloat(tmps[i]);
        }
        return rs;
      }
    }
    if (cls == 'string[]') {
      if (value == '') {
        return [];
      } else {
        tmps = value.split(',');
        return tmps;
      }
    }
    return value;
  },
};
function _setProp(n) {
  n.rows = []; //行数据
  n.names = [];
  n.cnindexs = {}; //索引队列
  n.keyIndexs = {}; //键值索引

  n.objCache = {};

  n.types = {}; //类型
  return n;
}
function _check_super(n, name) {
  if (n[name] !== null) {
    n['super_' + name] = n[name];
  }
}
function _setFunction(n) {
  n.init = function (source) {
    var tmprs = source.split(/\r\n|\r|\n/);
    var tmpcs;
    var ttpyes;
    var ri = 0,
      i;
    //如果有列名则先处理列名
    if (tmprs.length > ri) {
      ttpyes = tmprs[ri].split('\t');
      ri++;
      tmpcs = tmprs[ri].split('\t');
      for (i = 0; i < tmpcs.length; i++) {
        this.names.push(this.decode(tmpcs[i]));
        this.types[this.names[i]] = ttpyes[i];
      }
    }
    ri++;
    //处理行数据
    while (tmprs.length > ri) {
      if (tmprs[ri] == '') break;
      tmpcs = tmprs[ri].split('\t');
      var row = {};
      for (i = 0; i < tmpcs.length; i++) {
        row[this.names[i]] = this.decode(tmpcs[i]);
      }
      this.rows.push(row);
      ri++;
    }
  };
  n.convertByKey = function (key, value) {
    var cls = this.types[key];
    if (cls == null) return value;
    return ConfTable.convert(cls, value);
  };

  n.convertToObjRow = function (row) {
    var orow = {};
    for (var key in row) {
      var value = row[key];
      orow[key] = this.convertByKey(key, value);
    }
    return orow;
  };

  /**
   * 返回配置表的数据行数(不包括列名称的行)
   * @return
   */
  n.getRowCount = function () {
    var result = this.rows.length;
    return result;
  };
  n.getKeysByIndex = function (cname) {
    if (this.keyIndexs[cname] == null) {
      this.addIndex(cname);
    }
    if (this.keyIndexs[cname] == null) return null;

    var result = this.keyIndexs[cname].concat();

    return result;
  };
  /**
   * 获取指定行指定列的值
   * @param   index       行序号
   * @param   colName     列名称
   * @return
   */
  n.getValue = function (index, colName) {
    //if (this.rows[index] == null) return null;
    //return this.rows[index][colName];
    var row = this.getRow(index);
    if (row == null) return null;
    return row[colName];
  };
  /**
   * 获取指定行
   * @param   index
   * @return
   */
  n.getRow = function (index) {
    if (this.objCache[index] == null) {
      var row = this.rows[index];
      if (row == null) {
        cc.log('getRow获取配置表 数据为null' + index);
        return null;
      }
      //构造对象
      this.objCache[index] = this.convertToObjRow(row);
    }
    return this.objCache[index];
  };
  /**
   * 获取cname指定列值为value行的tarName列的值
   * @param   cname
   * @param   value
   * @param   tarName
   * @return
   */
  n.getValueByIndex = function (cname, value, tarName) {
    var r = this.getRowByIndex(cname, value);
    if (r == null) {
      //cc.log("getValueByIndex获取配置表 数据为null" + this.name + ":" + cname + ":" + value + ":" + tarName);
      return null;
    }
    return r[tarName];
  };
  /**
   * 搜索指定列值为value的第一行
   * @param   cname   列名称
   * @param   value   要搜索的值
   * @return
   */
  n.getRowByIndex = function (cname, value) {
    var rs = this.getRowsByIndex(cname, value);
    if (rs == null) {
      //cc.log("getRowByIndex获取配置表 数据为null " + this.name + ":" + cname + ":" + value);
      return null;
    }
    return rs[0];
  };
  /**
   * 搜索指定列值为value的行列表
   * @param   cname   列名称
   * @param   value   要搜索的值
   * @return  返回null表示没有搜索到
   */
  n.getRowsByIndex = function (cname, value) {
    if (this.cnindexs[cname] == null) {
      this.addIndex(cname);
    }
    return this.cnindexs[cname][value];
  };
  /**
   * 按列名称添加索引
   * @param   name
   */
  n.addIndex = function (name) {
    var index = {};
    var keys = [];
    for (var i = 0; i < this.rows.length; i++) {
      var key = this.rows[i][name];
      var okey = null;
      if (index[key] == null) {
        index[key] = [];
        keys.push(key);
      }
      index[key].push(this.convertToObjRow(this.rows[i]));
    }
    this.cnindexs[name] = index;
    this.keyIndexs[name] = keys;
  };

  n.encode = function (str) {
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/\r\n/g, '&rn;');
    str = str.replace(/\n/g, '&n;');
    str = str.replace(/\r/g, '&r;');
    str = str.replace(/\t/g, '&t;');
    return str;
  };
  n.decode = function (str) {
    str = str.replace(/&t;/g, '\t');
    str = str.replace(/&r;/g, '\r');
    str = str.replace('&n;', '\n');
    str = str.replace('&rn;', '\r\n');
    str = str.replace('&amp;', '&');
    return str;
  };

  return n;
}
exports.ConfTable = ConfTable;
